package org.example.config;

import org.example.security.MyAccessDeniedHandler;
import org.example.security.TokenAuthenticationFilter;
import org.example.security.TokenLoginFilter;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.security.authentication.dao.DaoAuthenticationProvider;
import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;

@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true, jsr250Enabled = true, securedEnabled = true)
public class SecurityConfig extends WebSecurityConfigurerAdapter {

    
    @Autowired
    private MyAccessDeniedHandler myAccessDeniedHandler;
    
    @Autowired
    private UserDetailsService userDetailsService;

    @Autowired
    private RedisTemplate<String, Object> redisTemplate;
    
    @Bean
    public PasswordEncoder passwordEncoder() {
        return new BCryptPasswordEncoder();
    }
    
    @Bean
    public DaoAuthenticationProvider authenticationProvider() {
        DaoAuthenticationProvider authenticationProvider = new DaoAuthenticationProvider();
        authenticationProvider.setPasswordEncoder(passwordEncoder());
        authenticationProvider.setUserDetailsService(userDetailsService);
        authenticationProvider.setHideUserNotFoundExceptions(true);
        return authenticationProvider;
    }

    

    @Override
    public void configure(HttpSecurity http) throws Exception {
        // 拦截规则
        http.authorizeRequests().antMatchers("/login", "/favicon.ico").permitAll()
                .anyRequest().authenticated(); 

        http.addFilter(new TokenLoginFilter(authenticationManager(), redisTemplate));
        
        http.addFilter(new TokenAuthenticationFilter(authenticationManager(), redisTemplate));
        
        // 权限不足处理器
        http.exceptionHandling().accessDeniedHandler(myAccessDeniedHandler);
        
        http.authenticationProvider(authenticationProvider());
        
        http.logout().logoutUrl("sys/logout").invalidateHttpSession(true);

        http.csrf().disable();

    }




}



